// hdu3016
// 题意：给定n(<=100000)块高度不同的木板，告诉你左右边界(li, ri)都是整数，
//       每个木板上有能量，可正可负。现在从高度最高的木板，可以选择
//       往左或者往右的边界，垂直下落到最近的一块木板，并且获得上面的能量，
//       如果没有木板就称掉到了地面。游戏过程中能量不可以小于等于0, 初始
//       能量值为100。
//       如果可以掉到地面，游戏成功，求掉落地面可以有的最大能量。否则表示
//       游戏失败，输出-1。
//
// 题解：用线段树找下落的下一个木板然后顺着推一遍就行。
//
// run: $exec < input
// opt: 0
// flag: -g
#include <iostream>
#include <cstring>
#include <algorithm>

int const maxn = 100007;

int next[3 * maxn], head[maxn], end_point[3 * maxn];
int alloc;

struct plank { int h, l, r, v; };

bool operator<(plank const & a, plank const & b)
{
	return a.h < b.h;
}

std::istream & operator>>(std::istream & is, plank & a)
{
	is >> a.h >> a.l >> a.r >> a.v;
	return is;
}

struct node
{
	int value, cover;
};

node tree[4 * maxn];

int dp[maxn];
plank da[maxn];
int n, len;

void add_edge(int x, int y)
{
//	std::cerr << da[x].h << "  --->  " << da[y].h << '\n';
	end_point[alloc] = y; next[alloc] = head[x]; head[x] = alloc++;
}

void init()
{
	len = 0;
	alloc = 1;
	std::memset(tree, 0, sizeof(tree));
	std::memset(head, 0, sizeof(head));
	for (int i = 0; i <= n; i++) dp[i] = -1;
}

void push_down(int id)
{
	node & t = tree[id];
	if (t.cover) {
		tree[id * 2].cover = tree[id * 2 + 1].cover = t.cover;
		tree[id * 2].value = tree[id * 2 + 1].value = t.value = t.cover;
		t.cover = 0;
	}
}

int get(int id, int l, int r, int x)
{
	if (x == l && r == x) return tree[id].value;
	push_down(id);
	int mid = (l + r) / 2;
	if (x <= mid) return get(id * 2, l, mid, x);
	else return get(id * 2 + 1, mid + 1, r, x);
}

void cover(int id, int l, int r, int tl, int tr, int co)
{
	if (tl <= l && r <= tr) {
		tree[id].cover = tree[id].value = co;
		return;
	}

	push_down(id);
	int mid = (l + r) / 2;
	if (tl <= mid) cover(id * 2, l, mid, tl, tr, co);
	if (mid < tr) cover(id * 2 + 1, mid + 1, r, tl, tr, co);
}

void build_graph()
{
	for (int i = 1; i <= n; i++) {
		int tl = get(1, 1, len, da[i].l);
		int tr = get(1, 1, len, da[i].r);
		add_edge(i, tl);
		add_edge(i, tr);
		cover(1, 1, len, da[i].l, da[i].r, i);
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	while (std::cin >> n) {
		init();
		for (int i = 1; i <= n; i++) {
			std::cin >> da[i];
			len = std::max(len, da[i].r);
		}
		da[0].h = 0; da[0].v = 0; da[0].l = 1; da[0].r = len;
		std::sort(da, da + n + 1);

		build_graph();

		dp[n] = 100 + da[n].v;
		for (int i = n; i; i--) {
			if (dp[i] <= 0) continue;
			for (int p = head[i]; p; p = next[p]) {
				int t = end_point[p];
				if (dp[i] + da[t].v <= 0) continue;
				dp[t] = std::max(dp[t], dp[i] + da[t].v);
			}
		}

		if (dp[0] <= 0) dp[0] = -1;
		std::cout << dp[0] << '\n';
	}
}

